home *** CD-ROM | disk | FTP | other *** search
- /********************************************************************
- ** Calculate the secure hash algorithm for a set of files.
- ** Algorithm from
- ** Stallings W, "SHA: the secure hash algorithm."
- ** Dr. Dobb's Journal, #213 (April 1994).
- **
- ** usage: sha [file ...]
- **
- ** Copyright 1994, G. Ralph Kuntz
- **
- ** This program is free software; you can redistribute it and/or modify
- ** it under the terms of the GNU General Public License as published by
- ** the Free Software Foundation; either version 2 of the License, or
- ** (at your option) any later version.
- **
- ** This program is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ** GNU General Public License for more details.
- **
- ** You should have received a copy of the GNU General Public License
- ** along with this program; if not, write to the Free Software
- ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- ********************************************************************/
-
- #include <stdlib.h>
- #include <stdio.h>
-
- #define BLOCK_COUNT (512L / 8) /* 512 bits into bytes */
-
- typedef enum { FALSE, TRUE } Bool;
-
- unsigned char *buffer;
- Bool wholeFile;
- long place;
- long size;
- char smallBuffer[BLOCK_COUNT];
-
- void
- initBuffer(FILE *fp)
- {
- wholeFile = FALSE;
- place = 0L;
- size = 0L;
- if (fseek(fp, 0L, SEEK_END) == 0) { /* Can get to EOF */
- size = ftell(fp);
- if (size != -1) { /* Can get position of EOF */
- long trueSize = size;
- size = (size & ~(BLOCK_COUNT - 1)) + BLOCK_COUNT; /* Round up to next
- ** multiple of
- ** BLOCK_COUNT */
- if ((buffer = (char *) malloc((size_t) size)) != NULL) { /* Can
- ** allocate
- ** enough
- ** memory */
- rewind(fp);
- if (fread(buffer, 1, trueSize, fp) == (size_t) trueSize) {
- long i;
- wholeFile = TRUE;
- buffer[trueSize] = 0x80; /* First pad byte */
- for (i = trueSize + 1; i < size - 4; i++)
- buffer[i] = 0;
- buffer[i++] = (unsigned char) ((trueSize & 0xff000000L) >> 24);
- buffer[i++] = (unsigned char) ((trueSize & 0xff0000L) >> 16);
- buffer[i++] = (unsigned char) ((trueSize & 0xff00) >> 8);
- buffer[i] = (unsigned char) (trueSize & 0xff);
- return;
- } else {
- rewind(fp);
- free(buffer);
- }
- }
- }
- } /* Cannot get to EOF */
- rewind(fp);
- buffer = smallBuffer;
- }
-
- void
- closeBuffer(void)
- {
- if (wholeFile)
- free(buffer);
- }
-
- Bool
- readBuffer(FILE *fp, unsigned long *destBuffer)
- {
- unsigned long ulTemp;
- unsigned char *pPlace;
- int i;
- if (!wholeFile) { /* Reading from small buffer */
- static long totalBytes = 0;
- int count;
- pPlace = buffer;
- if ((count = (int) fread(buffer, 1, BLOCK_COUNT, fp)) < BLOCK_COUNT) {
- if (count == 0 && feof(fp) != 0)
- return FALSE;
- totalBytes += count;
- buffer[count] = 0x80; /* Pad the buffer */
- for (i = count + 1; i < BLOCK_COUNT - 4; i++)
- buffer[i] = 0;
- buffer[i++] = (totalBytes & 0xff000000) >> 24;
- buffer[i++] = (totalBytes & 0xff0000) >> 16;
- buffer[i++] = (totalBytes & 0xff00) >> 8;
- buffer[i] = totalBytes & 0xff;
- } else /* Full buffer */
- totalBytes += BLOCK_COUNT;
- place = 0;
- } else { /* Reading from big buffer */
- if (place >= size)
- return FALSE;
- pPlace = &buffer[place];
- }
- for (i = 0; i < (BLOCK_COUNT / 4); i++) {
- ulTemp = ((unsigned long) *pPlace << 24) |
- ((unsigned long) *(pPlace + 1) << 16) |
- ((unsigned long) *(pPlace + 2) << 8) |
- (unsigned long) *(pPlace + 3);
- destBuffer[i] = ulTemp;
- pPlace += 4;
- }
- place += BLOCK_COUNT;
- return TRUE;
- }
-
- unsigned long mdQ[5];
-
- const unsigned long kReg[] = {
- 0x5a827999L,
- 0x5a827999L,
- 0x5a827999L,
- 0x5a827999L,
- 0x5a827999L,
- 0x5a827999L,
- 0x5a827999L,
- 0x5a827999L,
- 0x5a827999L,
- 0x5a827999L,
- 0x5a827999L,
- 0x5a827999L,
- 0x5a827999L,
- 0x5a827999L,
- 0x5a827999L,
- 0x5a827999L,
- 0x5a827999L,
- 0x5a827999L,
- 0x5a827999L,
- 0x5a827999L,
- 0x6ed9eba1L,
- 0x6ed9eba1L,
- 0x6ed9eba1L,
- 0x6ed9eba1L,
- 0x6ed9eba1L,
- 0x6ed9eba1L,
- 0x6ed9eba1L,
- 0x6ed9eba1L,
- 0x6ed9eba1L,
- 0x6ed9eba1L,
- 0x6ed9eba1L,
- 0x6ed9eba1L,
- 0x6ed9eba1L,
- 0x6ed9eba1L,
- 0x6ed9eba1L,
- 0x6ed9eba1L,
- 0x6ed9eba1L,
- 0x6ed9eba1L,
- 0x6ed9eba1L,
- 0x6ed9eba1L,
- 0x8f1bbcdcL,
- 0x8f1bbcdcL,
- 0x8f1bbcdcL,
- 0x8f1bbcdcL,
- 0x8f1bbcdcL,
- 0x8f1bbcdcL,
- 0x8f1bbcdcL,
- 0x8f1bbcdcL,
- 0x8f1bbcdcL,
- 0x8f1bbcdcL,
- 0x8f1bbcdcL,
- 0x8f1bbcdcL,
- 0x8f1bbcdcL,
- 0x8f1bbcdcL,
- 0x8f1bbcdcL,
- 0x8f1bbcdcL,
- 0x8f1bbcdcL,
- 0x8f1bbcdcL,
- 0x8f1bbcdcL,
- 0x8f1bbcdcL,
- 0xca62c1d6L,
- 0xca62c1d6L,
- 0xca62c1d6L,
- 0xca62c1d6L,
- 0xca62c1d6L,
- 0xca62c1d6L,
- 0xca62c1d6L,
- 0xca62c1d6L,
- 0xca62c1d6L,
- 0xca62c1d6L,
- 0xca62c1d6L,
- 0xca62c1d6L,
- 0xca62c1d6L,
- 0xca62c1d6L,
- 0xca62c1d6L,
- 0xca62c1d6L,
- 0xca62c1d6L,
- 0xca62c1d6L,
- 0xca62c1d6L,
- 0xca62c1d6L,
- };
-
- unsigned long wReg[80];
-
- #define CLS(R, S) (((R) >> (31 - S)) | ((R) << S))
- #define ROUND00_15(R) \
- aReg2 = CLS(aReg1, 5) + ((bReg1 & cReg1) | (~bReg1 & dReg1)) + \
- eReg1 + (wReg[R] = yReg[R]) + kReg[R]; \
- bReg2 = aReg1; \
- cReg2 = CLS(bReg1, 30); \
- dReg2 = cReg1; \
- eReg2 = dReg1; \
- wReg[R + 1] = yReg[R + 1]; \
- aReg1 = CLS(aReg2, 5) + ((bReg2 & cReg2) | (~bReg2 & dReg2)) + \
- eReg2 + (wReg[R + 1] = yReg[R + 1]) + kReg[R + 1]; \
- bReg1 = aReg2; \
- cReg1 = CLS(bReg2, 30); \
- dReg1 = cReg2; \
- eReg1 = dReg2
- #define ROUND16_19(R) \
- aReg2 = CLS(aReg1, 5) + ((bReg1 & cReg1) | (~bReg1 & dReg1)) + \
- eReg1 + \
- (wReg[R] = wReg[R - 16] ^ wReg[R - 14] ^ \
- wReg[R - 8] ^ wReg[R - 3]) + \
- kReg[R]; \
- bReg2 = aReg1; \
- cReg2 = CLS(bReg1, 30); \
- dReg2 = cReg1; \
- eReg2 = dReg1; \
- aReg1 = CLS(aReg2, 5) + ((bReg2 & cReg2) | (~bReg2 & dReg2)) + \
- eReg2 + \
- (wReg[R + 1] = wReg[R + 1 - 16] ^ wReg[R + 1 - 14] ^ \
- wReg[R + 1 - 8] ^ wReg[R + 1 - 3]) + \
- kReg[R + 1]; \
- bReg1 = aReg2; \
- cReg1 = CLS(bReg2, 30); \
- dReg1 = cReg2; \
- eReg1 = dReg2
- #define ROUND20_39_60_79(R) \
- aReg2 = CLS(aReg1, 5) + ((bReg1 ^ cReg1 ^ dReg1)) + \
- eReg1 + \
- (wReg[R] = wReg[R - 16] ^ wReg[R - 14] ^ \
- wReg[R - 8] ^ wReg[R - 3]) + \
- kReg[R]; \
- bReg2 = aReg1; \
- cReg2 = CLS(bReg1, 30); \
- dReg2 = cReg1; \
- eReg2 = dReg1; \
- aReg1 = CLS(aReg2, 5) + ((bReg2 ^ cReg2 ^ dReg2)) + \
- eReg2 + \
- (wReg[R + 1] = wReg[R + 1 - 16] ^ wReg[R + 1 - 14] ^ \
- wReg[R + 1 - 8] ^ wReg[R + 1 - 3]) + \
- kReg[R + 1]; \
- bReg1 = aReg2; \
- cReg1 = CLS(bReg2, 30); \
- dReg1 = cReg2; \
- eReg1 = dReg2
- #define ROUND40_59(R) \
- aReg2 = CLS(aReg1, 5) + ((bReg1 & cReg1) | (bReg1 & dReg1) | \
- (cReg1 & dReg1)) + \
- eReg1 + \
- (wReg[R] = wReg[R - 16] ^ wReg[R - 14] ^ \
- wReg[R - 8] ^ wReg[R - 3]) + \
- kReg[R]; \
- bReg2 = aReg1; \
- cReg2 = CLS(bReg1, 30); \
- dReg2 = cReg1; \
- eReg2 = dReg1; \
- aReg1 = CLS(aReg2, 5) + ((bReg2 & cReg2) | (bReg2 & dReg2) | \
- (cReg2 & dReg2)) + \
- eReg2 + \
- (wReg[R + 1] = wReg[R + 1 - 16] ^ wReg[R + 1 - 14] ^ \
- wReg[R + 1 - 8] ^ wReg[R + 1 - 3]) + \
- kReg[R + 1]; \
- bReg1 = aReg2; \
- cReg1 = CLS(bReg2, 30); \
- dReg1 = cReg2; \
- eReg1 = dReg2
-
- void
- hSHA(unsigned long *yReg)
- {
- unsigned long aReg1 = mdQ[0], bReg1 = mdQ[1], cReg1 = mdQ[2],
- dReg1 = mdQ[3], eReg1 = mdQ[4];
- unsigned long aReg2, bReg2, cReg2, dReg2, eReg2;
- ROUND00_15(0);
- ROUND00_15(2);
- ROUND00_15(4);
- ROUND00_15(6);
- ROUND00_15(8);
- ROUND00_15(10);
- ROUND00_15(12);
- ROUND00_15(14);
- ROUND16_19(16);
- ROUND16_19(18);
- ROUND20_39_60_79(20);
- ROUND20_39_60_79(22);
- ROUND20_39_60_79(24);
- ROUND20_39_60_79(26);
- ROUND20_39_60_79(28);
- ROUND20_39_60_79(30);
- ROUND20_39_60_79(32);
- ROUND20_39_60_79(34);
- ROUND20_39_60_79(36);
- ROUND20_39_60_79(38);
- ROUND40_59(40);
- ROUND40_59(42);
- ROUND40_59(44);
- ROUND40_59(46);
- ROUND40_59(48);
- ROUND40_59(50);
- ROUND40_59(52);
- ROUND40_59(54);
- ROUND40_59(56);
- ROUND40_59(58);
- ROUND20_39_60_79(60);
- ROUND20_39_60_79(62);
- ROUND20_39_60_79(64);
- ROUND20_39_60_79(66);
- ROUND20_39_60_79(68);
- ROUND20_39_60_79(70);
- ROUND20_39_60_79(72);
- ROUND20_39_60_79(74);
- ROUND20_39_60_79(76);
- ROUND20_39_60_79(78);
- mdQ[0] += aReg2;
- mdQ[1] += bReg2;
- mdQ[2] += cReg2;
- mdQ[3] += dReg2;
- mdQ[4] += eReg2;
- }
-
- unsigned long dataBuffer[BLOCK_COUNT / 4];
-
- int
- main(int argc, char **argv)
- {
- int i;
- for (i = 1; i < argc; i++) {
- FILE *fp;
- mdQ[0] = 0x67452301L;
- mdQ[1] = 0xefcdab89L;
- mdQ[2] = 0x98badcfeL;
- mdQ[3] = 0x10325476L;
- mdQ[4] = 0xc3d2e1f0L;
- if ((fp = fopen(argv[i], "rb")) == NULL) {
- fprintf(stderr, "sha: cannot open %s for reading\n", argv[i]);
- continue;
- }
- initBuffer(fp);
- while (readBuffer(fp, dataBuffer))
- hSHA(dataBuffer);
- printf("%08lx%08lx%08lx%08lx%08lx\t%s\n",
- mdQ[0], mdQ[1], mdQ[2], mdQ[3], mdQ[4], argv[i]);
- fclose(fp);
- }
- return EXIT_SUCCESS;
- }
-